package com.guli.ucenter.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.guli.base.exception.GuliException;
import com.guli.ucenter.entity.Member;
import com.guli.ucenter.service.MemberService;
import com.guli.ucenter.utils.ConstantPropertiesUtil;
import com.guli.ucenter.utils.HttpClientUtils;
import com.guli.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;

/**
 * @author ZHAOZHENYU
 * @since 2022/10/2
 */

@RequestMapping("/ucenter/wx")
//@CrossOrigin
@Controller         // 不用restController
public class WxApiController {

    @Autowired
    private MemberService memberService;

    // 微信扫描请求入口
    @GetMapping("/login")
    public String wxQRCode(){

        // 微信开放平台授权baseUrl
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";

        String redirectUrl = null;
        try {
            redirectUrl = URLEncoder.encode(ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        String wxQRCodeUrl = String.format(
                baseUrl,
                ConstantPropertiesUtil.WX_OPEN_APP_ID,
                redirectUrl,
                "guli-wxQRCode"
        );
        // 重定向
        return "redirect:"+wxQRCodeUrl;
    }

    // 微信扫描后回调 重定向到该方法
    @GetMapping("/callback")
    public String callback(String code, String state) {

        // 微信扫描得到授权临时票据code
//        System.out.println("code = " + code);
//        System.out.println("state = " + state);

        // Oauth服务器得到access_token的请求地址
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        String accessTokenUrl = String.format(
                baseAccessTokenUrl,
                ConstantPropertiesUtil.WX_OPEN_APP_ID,
                ConstantPropertiesUtil.WX_OPEN_APP_SECRET,
                code);
//        System.out.println("accessTokenUrl = " + accessTokenUrl);

        // httpClient请求地址得到返回值
        String authResult = null;
        try {
            authResult = HttpClientUtils.get(accessTokenUrl);
        } catch (Exception e) {
            e.printStackTrace();
            throw new GuliException(20001, "获取access_token失败");
        }

        //解析得到的json串
        Gson gson = new Gson();
        HashMap authMap = gson.fromJson(authResult, HashMap.class);
//        System.out.println("authMap = " + authMap);
        // 解析的json对象里面得到access_token和openid
        String accessToken = (String)authMap.get("access_token");
        String openid = (String)authMap.get("openid");

        // 用acess_token和openid访问微信的资源服务器，获取用户信息
        String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=%s" +
                "&openid=%s";
        String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openid);
        String userInfoResult = null;
        try {
            userInfoResult = HttpClientUtils.get(userInfoUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //解析json
        HashMap userInfoMap = gson.fromJson(userInfoResult, HashMap.class);
        System.out.println("userInfoMap = " + userInfoMap);
        String nickname = (String)userInfoMap.get("nickname");
        String headimgurl = (String)userInfoMap.get("headimgurl");

        //向数据库中插入一条记录
        Member member = new Member();
        member.setNickname(nickname);
        member.setOpenid(openid);
        member.setAvatar(headimgurl);

        // 查询数据库是否有openid 顺便取出id方便后面调用
        Member memberTemp = memberService.getOne(new QueryWrapper<Member>().eq("openid", openid));

        if (memberTemp == null){    // 没有登录过
            memberService.save(member);
            memberTemp = memberService.getOne(new QueryWrapper<Member>().eq("openid", openid));
        }else {
            memberService.update(member,new QueryWrapper<Member>().eq("openid", openid));
        }

        // TODO 生成token返回前端
        String jwtToken = JwtUtils.getJwtToken(memberTemp.getId(), nickname);

        return "redirect:http://localhost:3000?token=" + jwtToken;

    }

}
